package learn.two;

import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ClassLoadTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        // 引导类加载
//        System.out.println(String.class.getClassLoader());

//        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
//        while (systemClassLoader != null) {
//            System.out.println(systemClassLoader);
//            systemClassLoader = systemClassLoader.getParent();
//        }


        // 自定义类加载器
        System.out.println(FileClassLoader.registerAsParallelCapable());
        File file = new File("F:\\java\\Shihao.class");
        FileClassLoader fileClassLoader = new FileClassLoader(file);
                Class<?> aClass = fileClassLoader.loadClass("learn.Shihao");
        Method main = aClass.getMethod("main", String[].class);
        main.invoke(null, (Object) new String[]{"hello", "world"});


    }

    private static final class FileClassLoader extends ClassLoader {

        private final File file;

        public FileClassLoader(File file) {
            this.file = file;
        }

        /**
         * <?> 表示任何类型
         * @param name The <a href="#binary-name">binary name</a> of the class
         * @return
         * @throws ClassNotFoundException
         */
        @Override
        protected Class<?> findClass(String name) throws ClassNotFoundException {
            // class文件数据
            byte[] b = loadClassData();

            Class<?> aClass = defineClass(name, b, 0, b.length);
            return aClass;
        }

        public static boolean registerAsParallelCapable() {
            return ClassLoader.registerAsParallelCapable();
        }


        private byte[] loadClassData() {
            try (
                    FileInputStream stream = new FileInputStream(file);
            ) {
                return stream.readAllBytes();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

    }
}
